package com.keyingbo.concurrent.homework01;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 查询菜单数据组建成树状传给前端
 * 优化前：菜单数据量多，生成比较慢
 * 问题产生根本原因：菜单查询使用逐层递归查询数据库
 * 优化方向： 在原有的逻辑上，看能否用多线程方式去查询数据，多路汇合后，再组建数据返回
 * @Auther: KEYB
 * @Date: 2019-5-28 14:02
 * @Description:
 */
public class MenuCreateToQianDuan {
    public static ExecutorService pool = Executors.newCachedThreadPool();//线程池
    public static void createMenu(Menu parentMenu){
        //顶层菜单
        final List<Menu> topMenuList = findMenuByParentId(parentMenu.getId() , parentMenu.getLevel());
        if (topMenuList == null) return;
        //构建线程协调器
        final CountDownLatch countDownLatch = new CountDownLatch(topMenuList.size());
        //遍历某层级菜单
        for (final Menu menu : topMenuList) {
            pool.execute(new Runnable() {
                public void run() {
				    //… 递归处理逻辑
                    createMenu(menu);
                    //计数器减1
                    countDownLatch.countDown();
                }
            });
        }
        try {
            //多路汇集
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        parentMenu.setChildMenuList(topMenuList);
    }
    //从数据库获取数据
    private static List<Menu> findMenuByParentId(int parentId, int level) {
        if (level == 3) return null;
        int count = new Random().nextInt(10);
        List<Menu> topMenuList = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            Menu menu = new Menu();
            menu.setName("菜单_" + parentId + "_" + i);
            menu.setCode("Menu_" + parentId + "_" + i);
            menu.setId((int)Math.pow(10,level) + i);
            menu.setLevel(level + 1);
            topMenuList.add(menu);
        }
        return topMenuList;
    }

    public static void main(String[] args) {
        Menu menu = new Menu();
        menu.setLevel(0);
        menu.setId(-1);
        createMenu(menu);
        System.out.println(menu);
    }
}
